# 导入Flask核心模块：创建应用、渲染模板
from flask import Flask, render_template
# 导入Flask-SQLAlchemy扩展：提供ORM功能
from flask_sqlalchemy import SQLAlchemy
# 导入click：用于创建Flask自定义命令
import click
# 导入路径处理和系统判断模块
from pathlib import Path
import sys

# ---------------------- 1.初始化Flask应用 ----------------------
# 创建Flask应用实例，__name__表示当前模块作为应用目录
app = Flask(__name__)

# ---------------------- 2.数据库配置（Flask-SQLAlchemy方式） ----------------------
# 适配Windows/Linux/Mac的SQLite路径前缀
# Windows系统需要3个斜杠（sqlite:///），其他系统需要4个（sqlite:////）
SQLITE_PREFIX = 'sqlite:///' if sys.platform.startswith('win') else 'sqlite:////'

# 配置数据库连接地址：项目根目录下的data.db文件
# app.root_path获取当前应用的根目录，Path确保路径处理跨系统兼容
app.config['SQLALCHEMY_DATABASE_URI'] = SQLITE_PREFIX + str(Path(app.root_path) / 'data.db')

# 禁用修改跟踪功能（Flask-SQLAlchemy官方推荐，可提升性能）
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 初始化SQLAlchemy对象，关联当前Flask应用
# db对象将提供所有数据库操作功能（模型定义、会话管理、查询等）
db = SQLAlchemy(app)


# ---------------------- 3.定义数据库模型（对应数据库表） ----------------------
# 用户表：存储用户信息
class User(db.Model):  # 继承Flask-SQLAlchemy提供的db.Model基类
    __tablename__ = 'user'  # 数据库表名（不指定则默认使用类名小写）

    # 主键id：整数类型，自增（primary_key=True表示为主键）
    # 使用Flask-SQLAlchemy封装的db.Column和db.Integer
    id = db.Column(db.Integer, primary_key=True)
    # 用户名：字符串类型，长度限制20字符
    name = db.Column(db.String(20))


# 电影表：存储电影信息
class Movie(db.Model):
    __tablename__ = 'movie'  # 数据库表名

    id = db.Column(db.Integer, primary_key=True)  # 主键id
    title = db.Column(db.String(60))  # 电影标题：最长60字符
    year = db.Column(db.String(4))  # 电影年份：4字符（如1994、2023）


# ---------------------- 4.自定义命令：初始化数据库，生成测试数据 ----------------------
# 注册名为init-db的Flask命令（执行方式：flask init-db）
@app.cli.command('init-db')
# 添加--drop选项：是否先删除现有表再创建（默认不删除）
@click.option('--drop', is_flag=True, help='Delete existing tables before creating new ones.')
def init_database(drop):
    """Initialize the database: create tables (or recreate after dropping)."""
    if drop:  # 如果传入--drop参数，先删除所有表（会清空数据）
        db.drop_all()  # Flask-SQLAlchemy提供的删除表方法
    # 创建所有表（仅在表不存在时创建，存在则不操作）
    db.create_all()  # Flask-SQLAlchemy提供的创建表方法
    # 命令行输出成功提示
    click.echo('Database initialized successfully!')


# 注册名为forge的Flask命令（执行方式：flask forge）
@app.cli.command('forge')
def forge():
    """Generate fake test data for the database (overwrites existing data)."""
    db.drop_all()  # 先删除所有表（清空原有数据）
    db.create_all()  # 重新创建空表

    # 定义测试数据：1个用户 + 5部电影
    test_user = 'Test User'  # 测试用户名
    test_movies = [
        {'title': 'My Neighbor Totoro', 'year': '1988'},
        {'title': 'Leon', 'year': '1994'},
        {'title': 'WALL-E', 'year': '2008'},
        {'title': 'King of Comedy', 'year': '1999'},
        {'title': 'Dead Poets Society', 'year': '1989'}
    ]

    # 插入用户数据：创建User实例，添加到数据库会话
    user = User(name=test_user)
    db.session.add(user)  # 暂存到会话（未真正写入数据库）

    # 批量插入电影数据：遍历列表创建Movie实例，添加到会话
    for movie in test_movies:
        db.session.add(Movie(title=movie['title'], year=movie['year']))

    # 提交会话：将所有暂存操作真正写入数据库
    db.session.commit()
    # 命令行输出成功提示
    click.echo('Fake test data generated successfully!')


# ---------------------- 5.视图函数：主页（展示数据库数据） ----------------------
# 绑定根路由（访问http://127.0.0.1:5000时触发）

# 页面参考
@app.route('/demo')
def demo():
    return render_template('demo.html')


@app.route('/')
@app.route('/index')
@app.route('/home')
def index():
    return render_template('page/index.html')


# 仪表盘页面路由
@app.route('/dashboard')
def dashboard():
    # 可传递数据到模板（如统计数据），这里暂不传递
    return render_template('page/dashboard.html')


# 用户管理页面路由
@app.route('/users')
def users():
    return render_template('page/users.html')


# 产品管理页面路由
@app.route('/products')
def products():
    return render_template('page/products.html')


# 订单管理页面路由
@app.route('/orders')
def orders():
    return render_template('page/orders.html')


# 系统设置页面路由（添加到现有路由列表中）
@app.route('/settings')
def settings():
    # 可传递用户信息到模板（示例：获取当前登录用户名称）
    current_user = "周佳伟"  # 实际项目中可从数据库或登录状态获取
    return render_template('page/settings.html', user=current_user)

# 403 禁止访问错误处理
@app.errorhandler(403)
def forbidden(e):
    return render_template('error/403.html'), 403


# 404 页面不存在错误处理
@app.errorhandler(404)
def page_not_found(e):
    return render_template('error/404.html'), 404


# 500 服务器内部错误处理
@app.errorhandler(500)
def internal_server_error(e):
    return render_template('error/500.html'), 500


# ---------------------- 应用运行入口 ----------------------
if __name__ == '__main__':
    # 启动Flask开发服务器
    # debug=True：开启调试模式（代码修改后自动重载，显示详细错误信息）
    app.run(debug=True, port=9090)  # 新增 port=9090
